import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router'
// 封装axios
const request = axios.create({
  bastURL: '/api',
  timeout: 5000
})

/*
请求拦截器 --- 请求之前执行的函数
请求拦截器有几个参数?
 有两个参数，分别是两个回调函数(开始的时候不执行，回过头来，在特定的时机在执行
第一个回调函数，是请求发送成功以后执行的函数
第二个回调函数，是请求发送失败以后执行的函数.
*/

// 添加请求拦截器
request.interceptors.request.use(function(config) {
  // 在发送请求之前做些什么
  // console.log('1.请求成功走的代码', config)
  // 后面会在这里 给所有的请求 加一个请求头 里面携带token
  if (store.state.user.token) {
    config.headers.Authorization = `Bearer ${store.state.user.token}`
  }
  return config
}, function(error) {
  // 对请求错误做些什么
  // console.log('2.请求失败走的代码', error)
  return Promise.reject(error)
})

/*
响应拦截器 --- 服务器给相应数据到业务之前
响应拦截器的参数?
有2个参数，分别是2个回调函数!
第一个回调函数。 是服务器响应成功以后执行的回调函数
第二个回调函数，是服务器响应式失败以后 (481 5 43 484以后执行的回调函数
*/

// 添加响应拦截器
request.interceptors.response.use(function(response) {
  // 对响应数据做点什么
  // console.log('3.响应成功走的代码', response)
  // 在这里做一个前置判断 在响应拦截器里面，先做个判断，当返回值是Blob的实例时，就直接返回给业务调用方，这种也属于业务成动
  if (response.data instanceof Blob) return response.data // 返回了Blob对象
  // 需要进行一个条件判断 如果业务成功 则进行解构赋值 如果失败 应该提示用户 并用promise.reject返回
  if (response.data.success) {
  // 进行解构赋值
    return response.data
  } else {
    // 给用户一些使用提示，提示的话，不能使用alert，卡死浏览器，不好，要用element-ui的一些 提示组件 比喻:message
    // 这种代码是在.vue后缀文件里面使用的,因为this必须要是 vue组件实例
    // 而我们这个.js文件不能使用this,因为这个this指向的是undefined
    // this.message('这是一条消息提示')
    Message.error({ message: response.data.message })
    return Promise.reject(response)
  }
}, function(error) {
  // 对响应错误做点什么 http状态码  4xx 5xx 就会走这个函数
  // console.log('4.响应失败走的代码', error)
  /*
  // 涉及到Promise的底层， promise3个状态，pending 等待 resolve 成功 reject 失败
  这里如果 reject，那么在业务代码那边，就会执行catch的代码
  这里如果 resolve，那么在业务代码那边，就会执行 .then的代码
  因为这里已经是报错了，所以，我们这里必须写reject，告诉业务代码，我们这里报错了，请你用catch接受一下
  但是自己心里要清楚，如果这里写resolve，那么业务那边走的绝对是then里面的代码
  */
  //  需要做一个判断 如果报错401 没有token 则返回注册页面 并清空所有的token
  // 以后写比较长的对象的.的语法，都用?.去代替 直接.， 防止一些 token of undefined
  if (error?.response?.status === 401) {
    // 使用vuex里面的actions 清空token
    store.dispatch('user/logouAction')
    // 跳转登录页面
    router.push('/login')
  }
  return Promise.reject(error)
})

// 导出 request
export default request
